home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 10
/
FM Towns Free Software Collection 10.iso
/
ms_dos
/
tool
/
fwcp
/
src
/
cp.c
next >
Wrap
Text File
|
1995-03-09
|
6KB
|
271 lines
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <dos.h>
#include <fcntl.h>
#include <share.h>
#include "dir.h"
#define TRUE 1
#define FALSE 0
#define ERR (-1)
#define IO_BUFF_SIZE (16 * 1024)
static char *prog_name = "cp";
static int force_flg = TRUE;
static int recursive_flg = TRUE;
static int verbose_flg = TRUE;
static int update_flg = FALSE;
static int verify_flg = FALSE;
static int check_flg = TRUE;
static char io_buff[IO_BUFF_SIZE];
char *strform(char *tmp, char *str, int max);
/************
static void message(char *form, ...)
{
va_list arg;
char tmp[128];
va_start(arg, form);
vsprintf(tmp, form, arg);
va_end(arg);
BEEP();
SYSLINE(tmp);
}
*************/
char *file_name(char *file)
{
static char tmp[42];
return strform(tmp, file, 40);
}
static int file_error(char *file)
{
message("%s : %s", file_name(file), strerror(errno));
return ERR;
}
int file_copy(char *src_file, char *dis_file)
{
int sfp, dfp;
int ch, rc = 0;
unsigned read_size, write_size;
unsigned long file_size = 0L;
DIRECT st, dt;
if ( strcmp(src_file, dis_file) == 0 ) {
message("%s -> %s\n重複したコピ-は出来ません", src_file, dis_file);
return ERR;
}
if ( abort_check() )
return ERR;
if ( dos_stat(src_file, &st) )
return file_error(src_file);
if ( _dos_open(src_file, O_RDONLY, &sfp) )
return file_error(src_file);
if ( _dos_creatnew(dis_file, st.d_att, &dfp) ) {
if ( check_flg && !dos_stat(dis_file, &dt) ) {
BEEP();
for ( ; ; ) {
verbose("'%s' overwrite ? %s", file_name(dis_file),
(rc == 0 ? "([Yes]/No) ?" : "(Yes/[No]) ?"));
if ( (ch = yesno(&rc)) == ERR )
return ERR;
else if ( ch == TRUE )
break;
}
}
if ( update_flg != FALSE && !dos_stat(dis_file, &dt) &&
st.d_att == dt.d_att && st.d_size == dt.d_size &&
st.d_date <= dt.d_date && st.d_time <= dt.d_time ) {
_dos_close(sfp);
return FALSE;
}
if ( force_flg == FALSE || _dos_creat(dis_file, st.d_att, &dfp) ) {
_dos_close(sfp);
return file_error(dis_file);
}
}
if ( verbose_flg != FALSE )
verbose("COPY %s", file_name(dis_file));
for ( ; ; ) {
if ( _dos_read(sfp, io_buff, IO_BUFF_SIZE, &read_size) ) {
file_error(src_file);
goto ERROR;
}
if ( read_size == 0 )
break;
if ( _dos_write(dfp, io_buff, read_size, &write_size) ) {
file_error(dis_file);
goto ERROR;
}
if ( read_size != write_size ) {
message("%s : disk full ?", file_name(dis_file));
goto ERROR;
}
if ( verbose_flg != FALSE )
scale((unsigned long)read_size);
file_size += read_size;
}
if ( st.d_size != file_size ) {
message("%s : file read error ?", file_name(src_file));
goto ERROR;
}
if ( _dos_setftime(dfp, st.d_date, st.d_time) ) {
file_error(dis_file);
goto ERROR;
}
_dos_close(sfp);
_dos_close(dfp);
return FALSE;
ERROR:
_dos_close(sfp);
_dos_close(dfp);
if ( unlink(dis_file) )
file_error(dis_file);
return ERR;
}
static int chkdir(char *dir)
{
int ch;
int rc = 0;
DIRECT st;
if ( !dos_stat(dir, &st) ) {
if ( !IS_DIR((&st)) ) {
message("%s : not directory", file_name(dir));
return ERR;
}
if ( check_flg ) {
BEEP();
for ( ; ; ) {
verbose("%s : copy directory %s", file_name(dir),
(rc == 0 ? "([Yes]/No) ?" : "(Yes/[No]) ?"));
if ( (ch = yesno(&rc)) == ERR )
return ERR;
else if ( ch == TRUE )
break;
}
}
} else {
if ( mkdir(dir) )
return file_error(dir);
}
return FALSE;
}
static int dir_cmp(char *src, char *dis)
{
while ( *src != '\0' ) {
if ( *(src++) != *(dis++) )
return FALSE;
}
if ( *dis == '\0' || *dis == '\\' )
return TRUE;
return FALSE;
}
int root_check(char *dir)
{
return (dir[0] == '.' && (dir[1] == '.' || dir[1] == '\0') ? TRUE : FALSE);
}
int dir_copy(char *src_dir, char *dis_dir)
{
DIR *dir;
DIRECT *dp;
DIRECT st;
unsigned long sz;
char src_file[128];
char dis_file[128];
if ( dir_cmp(src_dir, dis_dir) ) {
message("%s -> %s\n重複したコピ-は出来ません", src_dir, dis_dir);
return ERR;
}
if ( abort_check() )
return ERR;
if ( chkdir(dis_dir) )
return ERR;
if ( (dir = opendir(src_dir, 0)) == NULL )
return file_error(src_dir);
while ( (dp = readdir(dir)) != NULL ) {
if ( root_check(dp->d_name) )
continue;
strcpy(src_file, path_make(src_dir, dp->d_name));
strcpy(dis_file, path_make(dis_dir, dp->d_name));
if ( IS_DIR(dp) ) {
if ( recursive_flg == FALSE )
continue;
if ( dir_copy(src_file, dis_file) )
goto ERROR;
continue;
}
if ( file_copy(src_file, dis_file) )
goto ERROR;
}
closedir(dir);
return FALSE;
ERROR:
closedir(dir);
return ERR;
}
unsigned long dir_size(char *src_dir)
{
DIR *dir;
DIRECT *dp;
unsigned long sz = 0;
char tmp[128];
if ( (dir = opendir(src_dir, 0)) == NULL )
return file_error(src_dir);
if ( verbose_flg != FALSE )
verbose("SIZE %s...", file_name(src_dir));
while ( (dp = readdir(dir)) != NULL ) {
if ( root_check(dp->d_name) )
continue;
if ( IS_DIR(dp) )
sz += dir_size(strcpy(tmp, path_make(src_dir, dp->d_name)));
else
sz += dp->d_size;
}
closedir(dir);
return sz;
}